package com.yonyou.brigade.third_parties.tuniu.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.props.PropUtil;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.basic_init.service.IUserCenterService;
import com.yonyou.brigade.third_parties.tuniu.constants.TuniuConstants;
import com.yonyou.brigade.third_parties.tuniu.model.TnDeptHistory;
import com.yonyou.brigade.third_parties.tuniu.model.TnUserHistory;
import com.yonyou.brigade.third_parties.tuniu.service.ITnDeptHistoryService;
import com.yonyou.brigade.third_parties.tuniu.service.ITnUserHistoryService;
import com.yonyou.brigade.third_parties.tuniu.service.ITuniuPublicService;
import com.yonyou.brigade.third_parties.tuniu.utils.SignUtils;
import com.yonyou.brigade.util.resultutil.HttpSendUtils;
import com.yonyou.ybzboot.starter.common.cipher.Base64Util;
import com.yonyou.ybzboot.starter.common.exception.BusinessException;
import com.yonyou.ybzboot.starter.common.util.StringUtil;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Administrator on 2018/11/1.
 */
@Service
public class TuniuPublicServiceImpl implements ITuniuPublicService {
    @Value("${tuniu.url}")
    private String baseUrl;

    @Autowired
    @Qualifier("userCenterServiceImpl")
    private IUserCenterService userCenterService;

    @Autowired
    @Qualifier("briChannelServiceImpl")
    private IBriChannelService briChannelService;

    @Autowired
    @Qualifier("tnUserHistoryServiceImpl")
    private ITnUserHistoryService tnUserHistoryService;

    @Autowired
    @Qualifier("tnDeptHistoryServiceImpl")
    private ITnDeptHistoryService tnDeptHistoryService;

    @Autowired
    private PropUtil propUtil;

    private static final Logger logger = LoggerFactory.getLogger(TuniuPublicServiceImpl.class);

    @Override
    public String ssoLogin(String tenant, String uid, String config, String pcOrH5) {
        String resultUrl="";
        String apiKey = "";
        String secretKey = "";
        String companyName = "";
        if(config != null){
            JSONObject conf = JSONObject.parseObject(config);
            apiKey = conf.getString("apiKey");
            secretKey=conf.getString("secretKey");
            companyName=conf.getString("companyName");
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date();
            String timestamp = sdf.format(date);
            String sign = SignUtils.getSign(apiKey,secretKey,timestamp);
            Map reqMap = new HashMap();
            reqMap.put("timestamp",timestamp);
            reqMap.put("sign",sign);
            reqMap.put("companyName",companyName);
            reqMap.put("apiKey",apiKey);
            Map reqData = new HashMap();
            reqData.put("uid",uid);
            if ("h5".equals(pcOrH5.toLowerCase())){
                reqData.put("loginType",2);
            } else {
                reqData.put("loginType",1);
            }
            reqMap.put("data",reqData);

            String reqStr = JSON.toJSONString(reqMap);
            logger.info("途牛商旅单点请求参数：" + reqStr);
            //调用途牛登录接口
            String rt = HttpSendUtils.sendPost(baseUrl + TuniuConstants.URL_LOGIN, reqStr);

            //途牛返回结果解码
            String decStr = null;
            try {
                decStr = Base64Util.decode(rt);
            } catch (Exception e) {
                e.printStackTrace();
            }
            logger.info("途牛商旅单点返回参数：" + decStr);
            if (!StringUtils.isEmpty(decStr)){
                JSONObject rtJson = JSON.parseObject(decStr);
                if (TuniuConstants.SUCCESS_CODE.equals(rtJson.getString("code"))){
                    JSONObject data = rtJson.getJSONObject("data");
                    resultUrl = data.getString("url");
                }else {
                    resultUrl = propUtil.getNO_ACCESS_URL();
                    return resultUrl;
                }
            }
        }catch (Exception e){
            throw  new BusinessException("获取途牛地址失败");
        }
        return  resultUrl;
    }


    @Override
    public void initDepart(BriChannel briChannel) {
        Map reqMap = new HashMap<>();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(date);
        reqMap.put("timestamp",timestamp);
        String companyName = null;
        if(briChannel != null){
            JSONObject config= JSON.parseObject(briChannel.getConfig());
            String apiKey = config.getString("apiKey");
            String secretKey = config.getString("secretKey");
            companyName = config.getString("companyName");
            String sign = SignUtils.getSign(apiKey,secretKey,timestamp);
            reqMap.put("sign",sign);
            reqMap.put("apiKey",apiKey);
        }

        UcUserDto ucUserDto = userCenterService.getCompleteUcUserDtoByPhone(briChannel.getPhone(),briChannel.getTenant());
        if (ucUserDto == null){
            throw new BusinessException("初始化途牛商旅部门时查询用户为空 phone:" + briChannel.getPhone());
        }
        reqMap.put("companyName",companyName);
        Map deptReq = new HashMap<>();
        //目前以组织开通，默认一级部门
        deptReq.put("deptName",ucUserDto.getOrgName());

//        deptReq.put("deptName","测试1");

        deptReq.put("deptLevel","1");
        reqMap.put("data",deptReq);
        String jsonStr = JSONObject.toJSONString(reqMap);
        //调用途牛新增部门接口
        //返回结果
        logger.info("初始化途牛部门传送信息:" + jsonStr);
        String rt = HttpSendUtils.sendPost(baseUrl + TuniuConstants.URL_ADDDEPT,jsonStr);
        //途牛返回结果解码
        String decStr = null;
        try {
            decStr = Base64Util.decode(rt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("初始化途牛部门返回信息:" + decStr);
        if (!StringUtil.isEmpty(rt) && TuniuConstants.SUCCESS_CODE.equals(JSONObject.parseObject(decStr).getString("code"))){
            JSONObject rtJson = JSONObject.parseObject(decStr);
            JSONObject data = rtJson.getJSONObject("data");
            TnDeptHistory tnDeptHistory = new TnDeptHistory();
            tnDeptHistory.setTenant(briChannel.getTenant());
            tnDeptHistory.setOrgpk(briChannel.getOrgpk());
            tnDeptHistory.setDeptName(ucUserDto.getOrgName());

//            tnDeptHistory.setDeptName("测试1");

            tnDeptHistory.setDeptId(data.getString("deptId"));
            tnDeptHistory.setDeptLevel(1);
            tnDeptHistoryService.insert(tnDeptHistory);
        }
    }

    @Override
    public String pushTravelApplyOrder(String tenant, String orgPk, JSONObject applyOrderJson) {
        logger.info("途牛申请单信息:" + applyOrderJson.toString());
        Map reqMap = new HashMap<>();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(date);
        String companyName = null;
        BriChannel briChannel = briChannelService.getEnableInfoByTenantOrg(tenant, orgPk, "tuniu");
        reqMap.put("timestamp",timestamp);
        if (briChannel != null){
            JSONObject config= JSON.parseObject(briChannel.getConfig());
            String apiKey = config.getString("apiKey");
            String secretKey = config.getString("secretKey");
            companyName = config.getString("companyName");
            String sign = SignUtils.getSign(apiKey,secretKey,timestamp);
            reqMap.put("sign",sign);
            reqMap.put("apiKey",apiKey);
        }
        reqMap.put("companyName",companyName);
        reqMap.put("data",applyOrderJson);
        String jsonStr = JSONObject.toJSONString(reqMap);
        //发送途牛申请单信息
        logger.info("发送途牛申请单信息:" + jsonStr);
        String rt = HttpSendUtils.sendPost(baseUrl + TuniuConstants.URL_APPLYORDER,jsonStr);
        //途牛返回结果解码
        String decStr = null;
        try {
            decStr = Base64Util.decode(rt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("请求途牛申请单返回信息:" + decStr);
        if (!StringUtil.isEmpty(rt) && TuniuConstants.SUCCESS_CODE.equals(JSONObject.parseObject(decStr).getString("code"))){
            logger.info("途牛申请单推送成功!");
        } else {
            logger.info("途牛申请单推送失败!");
        }
        return decStr;
    }

    @Override
    public void updateUser(Map parmas, String config) {
        Map reqMap = new HashMap<>();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(date);
        reqMap.put("timestamp",timestamp);

        JSONObject jsonObject= JSON.parseObject(config);
        if (jsonObject != null){
            String apiKey = jsonObject.getString("apiKey");
            String secretKey = jsonObject.getString("secretKey");
            String companyName = jsonObject.getString("companyName");
            String sign = SignUtils.getSign(apiKey,secretKey,timestamp);
            reqMap.put("sign",sign);
            reqMap.put("apiKey",apiKey);

            reqMap.put("companyName", companyName);
        }

        reqMap.put("data",parmas);

        //调用途牛更新员工接口
        //返回结果
        logger.info("调用途牛商旅更新人员接口信息：" + JSONObject.toJSONString(reqMap));
        String rt = HttpSendUtils.sendPost(baseUrl + TuniuConstants.URL_UPDATEEMPLOYEE,JSONObject.toJSONString(reqMap));

        String decStr = null;
        try {
            decStr = Base64Util.decode(rt);
        } catch (Exception e) {
            logger.info("转码异常！");
            e.printStackTrace();
        }
        logger.info("途牛商旅更新人员接口返回信息：" + decStr);
        if (!StringUtils.isEmpty(decStr) && TuniuConstants.SUCCESS_CODE.equals(JSON.parseObject(decStr).getString("code"))){
            Map userMap = new HashMap();
            userMap.put("uid",parmas.get("uid").toString());
            userMap.put("phone",parmas.get("phone").toString());

            tnUserHistoryService.updateByUid(userMap);
            logger.info("更新途牛商旅人员信息完成！");
        }
    }

    @Override
    public void insertUser(Map parmas, String config) {
        Map result = new HashMap<>();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(date);
        result.put("timestamp",timestamp);

        JSONObject jsonObject= JSON.parseObject(config);
        if (jsonObject != null){
            String apiKey = jsonObject.getString("apiKey");
            String secretKey = jsonObject.getString("secretKey");
            String companyName = jsonObject.getString("companyName");
            String sign = SignUtils.getSign(apiKey,secretKey,timestamp);
            result.put("sign",sign);
            result.put("apiKey",apiKey);

            result.put("companyName", companyName);
        }

        result.put("data",parmas);

        //调用途牛新增员工接口
        //返回结果
        logger.info("调用途牛商旅新增人员接口信息：" + JSONObject.toJSONString(result));
        String rt = HttpSendUtils.sendPost(baseUrl + TuniuConstants.URL_ADDEMPLOYEE,JSONObject.toJSONString(result));

        String decStr = null;
        try {
            decStr = Base64Util.decode(rt);
        } catch (Exception e) {
            logger.info("转码异常！");
            e.printStackTrace();
        }
        logger.info("途牛商旅新增人员接口返回信息：" + decStr);
        if (!StringUtils.isEmpty(decStr) && TuniuConstants.SUCCESS_CODE.equals(JSON.parseObject(decStr).getString("code"))){
            TnUserHistory tnUserHistory = new TnUserHistory();
            tnUserHistory.setPhone(parmas.get("phone").toString());
            tnUserHistory.setDeptId(parmas.get("deptId").toString());
            tnUserHistory.setUserName(parmas.get("employeeName").toString());
            tnUserHistory.setPersonCode(parmas.get("employeeNo").toString());
            tnUserHistory.setUserNo(JSON.parseObject(decStr).getString("data"));

            tnUserHistoryService.insert(tnUserHistory);
            logger.info("同步途牛商旅人员信息完成！");
        }
    }

    @Override
    public JSONObject pushApplayOrder(BriChannel channel, String tenant, String orgPk, JSONObject applyOrderJson) {
        JSONObject resultObject = new JSONObject();
        logger.info("途牛申请单信息:" + applyOrderJson.toString());
        logger.info("开始拼装同步申请单数据");
        JSONObject data = processApplyData(applyOrderJson,tenant);

        if (data.getString("msg") != null && !"".equals(data.getString("msg"))){
            resultObject.put("success",false);
            resultObject.put("msg",data.getString("msg"));
            return resultObject;
        }
        Map reqMap = new HashMap<>();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(date);
        String companyName = null;
        BriChannel briChannel = briChannelService.getEnableInfoByTenantOrg(tenant, orgPk, "tuniu");
        reqMap.put("timestamp",timestamp);
        if (briChannel != null){
            JSONObject config= JSON.parseObject(briChannel.getConfig());
            String apiKey = config.getString("apiKey");
            String secretKey = config.getString("secretKey");
            companyName = config.getString("companyName");
            String sign = SignUtils.getSign(apiKey,secretKey,timestamp);
            reqMap.put("sign",sign);
            reqMap.put("apiKey",apiKey);
        }
        reqMap.put("companyName",companyName);
        reqMap.put("data",data);
        String jsonStr = JSONObject.toJSONString(reqMap);
        //发送途牛申请单信息
        logger.info("发送途牛申请单信息:" + jsonStr);
        String rt = HttpSendUtils.sendPost(baseUrl + TuniuConstants.URL_APPLYORDER,jsonStr);
        //途牛返回结果解码
        String decStr = null;
        try {
            decStr = Base64Util.decode(rt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("请求途牛申请单返回信息:" + decStr);
        if (!StringUtil.isEmpty(rt) && TuniuConstants.SUCCESS_CODE.equals(JSONObject.parseObject(decStr).getString("code"))){
            logger.info("途牛申请单推送成功!");
            resultObject.put("success",true);
        } else {
            logger.info("途牛申请单推送失败!");
            resultObject.put("success",false);
            resultObject.put("msg",decStr);
        }
        return resultObject;
    }

    private JSONObject processApplyData(JSONObject applyOrderJson, String tenant) {
        JSONObject applyData = new JSONObject();

        JSONObject nodeBusinessTrip = applyOrderJson;
        JSONObject special = nodeBusinessTrip.getJSONObject("special");
        applyData.put("applyCode",special.getString("applayNumber"));
        applyData.put("applyName",special.getString("tuniuApplyName"));
        applyData.put("phone",special.getString("tuniuPhone"));

        String openType = special.getString("openType");

        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date startDate = nodeBusinessTrip.getDate("startDate");
        Date endDate = nodeBusinessTrip.getDate("endDate");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.DATE,1);
        String expireDate = f.format(calendar.getTime());

        if (nodeBusinessTrip.getDate("createTime") != null) {
            applyData.put("applyTime",sdf.format(nodeBusinessTrip.getDate("createTime")));
        }
        if (startDate != null) {
            applyData.put("effectiveDate",f.format(startDate));
        }
        applyData.put("expireDate",expireDate);
        applyData.put("travelReason",nodeBusinessTrip.getString("descript"));
        //申请单状态 1已审批 2已作废 3部分使用 4已使用
        applyData.put("status","1");

        // 单据详情
        JSONArray travelList = nodeBusinessTrip.getJSONArray("nodeBusinessTravelList");

        //行程信息
        JSONArray applyOrderJourneyArr = new JSONArray();
        //实际出行人
        Map<String,String> companionMap = getPassenger(nodeBusinessTrip.getString("actualPedestrian"),tenant,nodeBusinessTrip.getString("userId"),openType, nodeBusinessTrip.getString("companion"));
        //出差人信息
        JSONArray travellerArray = new JSONArray();

        for (Map.Entry<String,String> traveler : companionMap.entrySet()){
            JSONObject travelerJSON = new JSONObject();
            travelerJSON.put("travellerName",traveler.getValue());
            travelerJSON.put("phone",traveler.getKey());
            travellerArray.add(travelerJSON);
        }
        if (travelList != null && travelList.size() > 0){
            for (int i = 0; i < travelList.size(); i++) {
                JSONObject travel = travelList.getJSONObject(i);
                String tripWay = travel.getString("tripWay");
                String toCity = travel.getString("toCity");
                String fromCity = travel.getString("fromCity");
                Integer journeyWay = null;
                Integer productCategory = null;
                if ("飞机".equals(tripWay)){
                    //飞机行程信息
                    String tripType = travel.getString("tripType");
                    if ("RT".equals(tripType)){
                        journeyWay = 2;
                    } else {
                        journeyWay = 1;
                    }
                    productCategory = 1;
                }else if ("火车".equals(tripWay)){
                    //火车行程信息
                    String tripType = travel.getString("tripType");
                    if ("RT".equals(tripType)){
                        journeyWay = 2;
                    } else {
                        journeyWay = 1;
                    }
                    productCategory = 2;
                }

                //酒店入住信息
                if (travel.getBigDecimal("yghotelcost") != null && travel.getBigDecimal("yghotelcost").compareTo(new BigDecimal(0)) > 0){
                    productCategory += 4;
                }

                JSONObject applyOrderJourney = getParams(journeyWay,fromCity,toCity,travel,String.valueOf(productCategory),1,startDate,endDate);

                applyOrderJourney.put("travellers",travellerArray);

                applyOrderJourneyArr.add(applyOrderJourney);
            }
        }

        applyData.put("journeys",applyOrderJourneyArr);

        return applyData;
    }

    public JSONObject getParams(Integer journeyWay, String deptCity, String arrCity, JSONObject travel, String productCategory, Integer status , Date startDate, Date endDate){
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        JSONObject params = new JSONObject();
        params.put("journeyWay",journeyWay);
        params.put("deptCity",deptCity);
        params.put("arrCity",arrCity);
        if (travel.getDate("begindate") != null){
            params.put("startDate",sf.format(travel.getDate("begindate")));
        }else {
            params.put("startDate",sf.format(startDate));
        }
        if (travel.getDate("enddate") != null){
            params.put("endDate",sf.format(travel.getDate("enddate")));
        }else {
            params.put("endDate",sf.format(endDate));
        }
        params.put("travelReason",travel.getString("descript"));
        params.put("productCategory",productCategory);
        params.put("status",status);
        return params;
    }
    /**
     * 转换companion中的字符
     * @param companion
     * @return
     */
    public static String convertTraveler(String companion){
        String convertStr = companion;
        if (companion.contains("（")){
            convertStr = companion.replaceAll("（",",");
        }
        if (companion.contains("(")){
            convertStr = convertStr.replaceAll("\\(",",");
        }
        if (companion.contains("）")){
            convertStr = convertStr.replaceAll("）","");
        }
        if (companion.contains(")")){
            convertStr = convertStr.replaceAll("\\)","");
        }
        if (companion.contains("，")){
            convertStr = convertStr.replaceAll("，",",");
        }
        if (companion.contains("、")){
            convertStr = convertStr.replaceAll("、",",");
        }
        return convertStr;
    }


    /**
     * 获取实际出行人
     * @param passengerIds
     * @param tenant
     * @param userId
     * @param openType
     * @param companion 旧的实际出行人为手输格式，支持格式  张三（17934125896），李四（14536897562）
     * @return
     */
    private Map<String,String> getPassenger(String passengerIds,String tenant,String userId,String openType, String companion){
        Map<String,String> companionMap = new HashMap<>();
        if (StringUtils.isNotBlank(passengerIds)){
            passengerIds = convertTraveler(passengerIds);
        }
        List<UcUserDto>  sscUserList = userCenterService.getCompleteUcUserDtoByUserid(Arrays.asList(userId),tenant);

        if (!StringUtils.isEmpty(companion)){
            companion = convertTraveler(companion);
            String[] split = companion.split(",");
            for (String str : split) {
                String[] strings = str.split(":");
                if (strings.length > 1){
                    String phoneNo = strings[1];
                    String userName = strings[0];
                    //如果手输实际出行人和制单人名字一致，则忽略
                    if (split.length == 1 && userName.equals(sscUserList.get(0).getUserName())){
                        continue;
                    }
                    companionMap.put(phoneNo,userName);
                }
            }
        }

        if (StringUtils.isNotBlank(passengerIds)){
            String[] split = passengerIds.split(";");
            List<String> persionIds = new ArrayList<>();
            for (String str : split) {
                if (str.split(",").length>0){
                    persionIds.add(str.split(",")[0]);
                }
            }

            List<UcUserDto>  companionUser = null;
            if ("nc".equals(openType)){
                companionUser = userCenterService.getCompleteUcUserByPersonIds(persionIds,tenant);
            }else {
                companionUser = userCenterService.getCompleteUcUserDtoByUserid(persionIds,tenant);
            }
            if (companionUser != null && companionUser.size() > 0 ){
                for (UcUserDto ucUserDto : companionUser) {
                    companionMap.put(ucUserDto.getPhone(),ucUserDto.getUserName());
                }
            }else {
                logger.info("用户中心未找到实际出行人:" + persionIds.toString());
                //TODO 用户中心未找到人员时同步erp用户，再次查找。
                throw new BusinessException("用户中心未找到部分实际出行人");
            }

        }else {
            if (companionMap.size() <= 0){
                companionMap.put(sscUserList.get(0).getPhone(),sscUserList.get(0).getUserName());
            }
        }
        return  companionMap;
    }
}